<!--视频库-教案库-案例库-文献库 弹窗-->
<template>
  <div>
    <el-dialog title="信息详情" v-model="dialogVisible" width="50%" :close-on-click-modal="false" @close="closeDialog" center>
      <div class="dialog-content">
        <el-form ref="libraryFormRef" :model="libraryInformation" label-position="right" label-width="125">
          <!--文献库 不需要填写人员姓名-->
          <el-form-item
            label="姓名："
            prop="userName"
            v-if="libraryTypeId !== 'literature'"
            :rules="[
              { required: !disabled, message: '请选择姓名', trigger: 'blur' },
              { max: 200, message: '姓名不可超过200个字', trigger: 'blur' },
            ]"
          >
            <div v-if="!disabled" class="personnel-input" @click="userSelectClick('personnel')">
              <span v-if="!libraryInformation.userName" class="input-personnelList">请选择人员</span>
              <el-tag v-else closable class="input-item" type="info" @close="personnelDeletion">
                {{ libraryInformation.userName }}
              </el-tag>
            </div>
            <el-input v-else v-model="libraryInformation.userName" disabled />
          </el-form-item>
          <!-- 只有文献库不展示员工编号 -->
          <el-form-item
            v-if="libraryTypeId !== 'literature'"
            label="员工编号："
            prop="userId"
            :rules="[{ required: !disabled, message: '请输入员工编号', trigger: 'blur' }]"
          >
            <el-input v-model="libraryInformation.userId" disabled />
          </el-form-item>
          <el-form-item
            v-if="libraryTypeId !== 'literature'"
            label="支部："
            prop="partyOrgName"
            :rules="[{ required: !disabled, message: '请选择支部', trigger: 'blur' }]"
          >
            <el-input v-model="libraryInformation.partyOrgName" placeholder="请输入支部" :disabled="disabled" />
          </el-form-item>
          <el-form-item
            v-if="libraryTypeId !== 'literature'"
            label="公司："
            prop="companyName"
            :rules="[{ required: !disabled, message: '请选择公司名称', trigger: 'blur' }]"
          >
            <el-input v-model="libraryInformation.companyName" placeholder="请输入公司" :disabled="disabled" />
          </el-form-item>
          <el-form-item
            label="标题："
            prop="title"
            :rules="[
              { required: !disabled, message: '请输入标题', trigger: 'blur' },
              { max: 200, message: '标题不可超过200个字', trigger: 'blur' },
            ]"
          >
            <el-input v-model="libraryInformation.title" placeholder="请输入标题" :disabled="disabled" />
          </el-form-item>
          <!-- 只有文献库可以新增来源和关键词 -->
          <template v-if="libraryTypeId === 'literature'">
            <el-form-item
              label="来源："
              prop="source"
              :rules="[
                { required: !disabled, message: '请输入来源', trigger: 'blur' },
                { max: 200, message: '来源不可超过200个字', trigger: 'blur' },
              ]"
            >
              <el-input v-model="libraryInformation.source" placeholder="请输入来源" :disabled="disabled" />
            </el-form-item>
            <el-form-item
              label="关键词："
              prop="keyWord"
              :rules="[
                { required: !disabled, message: '请输入关键词', trigger: 'blur' },
                { max: 200, message: '关键词不可超过200个字', trigger: 'blur' },
              ]"
            >
              <el-input
                type="textarea"
                :autosize="{ minRows: 2, maxRows: 4 }"
                v-model="libraryInformation.keyWord"
                placeholder="请输入关键词"
                :disabled="disabled"
              />
            </el-form-item>
          </template>
          <el-form-item label="简介：" prop="briefIntroduction" v-if="libraryTypeId !== 'literature'">
            <el-input v-model="libraryInformation.briefIntroduction" placeholder="请输入简介" :disabled="disabled" />
          </el-form-item>
          <!--教案库 文献库 需要上传附件-->
          <el-form-item
            label="附件："
            prop="fileList"
            v-if="libraryTypeId === 'lessonPlan' || libraryTypeId === 'literature'"
            :rules="[{ required: !disabled, message: '请上传附件', trigger: 'blur' }]"
          >
            <file-upload
              ref="rectifyAndRef"
              :disabled="disabled"
              :isShowTip="!disabled"
              :limit="100"
              :fileSize="200"
              :uploading="uploading"
              :percentage="percentage"
              v-model:fileList="libraryInformation.fileList"
              @handleUploadRequest="(files) => handleUploadRequest(files, 'file')"
              @handleDelete="(index) => handleDelete(index, 'file')"
            ></file-upload>
          </el-form-item>
          <!--视频库 案例库 需要选择宣讲时间-->
          <el-form-item
            label="宣讲时间："
            prop="lectureTime"
            v-if="libraryTypeId === 'video' || libraryTypeId === 'case'"
            :rules="[{ required: !disabled, message: '请选择宣讲时间', trigger: 'blur' }]"
          >
            <el-date-picker
              :disabled="disabled"
              v-model="libraryInformation.lectureTime"
              type="date"
              placeholder="请选择宣讲时间"
              value-format="YYYY-MM-DD"
              style="width: 100%"
            >
            </el-date-picker>
          </el-form-item>
          <!--视频库 需要上传视频附件-->
          <el-form-item
            label="视频附件："
            prop="videoName"
            v-if="libraryTypeId === 'video'"
            :rules="[{ required: !disabled, message: '请上传视频附件', trigger: 'blur' }]"
          >
            <file-upload
              ref="videoUploadRef"
              :disabled="disabled"
              :isShowTip="!disabled"
              :limit="1"
              :fileSize="4096"
              :fileTypes="videoType"
              :uploading="uploading"
              :percentage="percentage"
              v-model:fileList="videoAttachmentList"
              @handleUploadRequest="(files) => handleUploadRequest(files, 'video')"
              @handleDelete="(index) => handleDelete(index, 'video')"
            ></file-upload>
          </el-form-item>
          <!--案例库 需要填写案例内容-->
          <el-form-item
            label="案例内容："
            prop="caseContent"
            v-if="libraryTypeId === 'case'"
            :rules="{ required: !disabled, message: '请输入案例内容', trigger: 'blur' }"
          >
            <Editor v-model="libraryInformation.caseContent" :read-only="disabled" :minHeight="200" style="width: 100%" />
          </el-form-item>
          <!-- 编辑状态时 不展示处理意见 -->
          <template v-if="auditStatus !== 'edit'">
            <!-- 没有上一环节处理意见时 不展示 -->
            <el-form-item label="上一环节处理意见：" prop="backIdea" v-if="libraryInformation.opinion">
              <el-input v-model="libraryInformation.opinion" disabled />
            </el-form-item>
            <!-- 处理状态时, 可以编辑处理建议, 展示效验 -->
            <el-form-item
              v-if="auditStatus === 'handle'"
              label="处理意见："
              prop="currentOpinion"
              :rules="[
                { required: auditStatus === 'handle', message: '请输入处理意见', trigger: 'blur' },
                { max: 200, message: '处理意见不可超过200个字', trigger: 'blur' },
              ]"
            >
              <el-input
                v-model="libraryInformation.currentOpinion"
                :disabled="auditStatus === 'view'"
                placeholder="请输入处理意见"
              />
            </el-form-item>
          </template>
        </el-form>
      </div>
      <template #footer>
        <div style="margin-bottom: 20px">
          <div v-if="!disabled">
            <el-button type="primary" @click="informationSubmission('informationSave')">保存</el-button>
            <el-button type="success" @click="informationSubmission('informationSubmit')">提交</el-button>
            <!-- 案例库才有预览功能 -->
            <el-button type="warning" @click="casePreview" v-if="libraryTypeId === 'case'">预览</el-button>
            <el-button @click="dialogVisible = false">关闭</el-button>
          </div>
          <!-- 只有处理时 才可以展示审核按钮 -->
          <div v-if="disabled && auditStatus === 'handle'">
            <el-button type="primary" @click="reviewAndSubmit('审核通过', 'pass')">审核通过</el-button>
            <el-button @click="reviewAndSubmit('审核退回', 'sendBack')">审核退回</el-button>
            <el-button @click="dialogVisible = false">关闭</el-button>
          </div>
        </div>
      </template>
    </el-dialog>
    <!--支部选择弹窗-->
    <PersonnelSelection
      ref="personnelSelectionDialog"
      @submit="branchSubmit"
      :maxCount="maxBranch"
      :personnel-or-branch="personnelOrBranch"
      :personnelEcho="personnelEcho"
      :multiple="true"
    ></PersonnelSelection>
    <!--案例库预览弹窗-->
    <detailedContentDialog ref="contentDialogRef" :descriptionList="descriptionList"></detailedContentDialog>
  </div>
</template>

<script setup>
import { ref, watch } from "vue";
import { ElMessage } from "element-plus";
import PersonnelSelection from "@/components/flowDemo/PersonnelSelectionDialog.vue";
import { queryUsers, queryCompany, attachmentEcho } from "@/api/navigationLecture";
import detailedContentDialog from "@/components/Dialog/detailedContentDialog";
import request from "@/utils/request";
import { SHOW_PROGRESS_AFTER_UPLOAD, UPLOAD_FINAL_PROGRESS } from "@/utils/assetsLibrary";
import lodash from "lodash";
const { proxy } = getCurrentInstance();
const emit = defineEmits();
const props = defineProps({
  // 库种类型id
  libraryTypeId: {
    type: String,
    default: "",
  },
  // 编辑人员信息数据列表
  editInformation: {
    type: Object,
    default: {},
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false,
  },
  // 审核状态 view: 查看, handle: 处理, edit: 编辑
  auditStatus: {
    type: String,
    default: "view",
  },
});
const libraryFormRef = ref(); // 弹窗表单ref值
const dialogVisible = ref(false); // 弹窗状态
const videoType = ref(new Set(["mp4"])); // 视频上传类型
const uploading = ref(false); // 上传进度条
const percentage = ref(0); // 上传进度百分比
const personnelOrBranch = ref(""); // 人员或支部
const isNeedMaxCount = ref(false); // 是否需要最大数量限制
const libraryInformation = ref({
  id: "",
  companyName: "", // 公司名称
  partyOrgName: "", // 支部名称
  briefIntroduction: "", // 简介
  userName: "", // 人员姓名
  userId: "", // 人员id(员工编号)
  videoId: "", // 视频id
  videoName: "", // 视频附件
  lectureTime: "", // 宣讲时间
  title: "", // 标题
  fileList: [], // 附件
  caseContent: "", // 案例内容
  keyWord: "", // 关键词
  source: "", // 来源
  opinion: "", // 上一环节处理意见
  currentOpinion: "", // 处理意见
}); // 弹窗信息
const videoAttachmentList = ref([]); // 视频附件列表
const personnelSelectionDialog = ref(); //支部选择弹窗
const maxBranch = ref(10); // 支部选择数量
const contentDialogRef = ref(); // 案例库预览弹窗的ref值
const descriptionList = ref({}); // 案例库预览详细内容
const personnelEcho = ref([]); // 人员回显列表
/**
 * 监听事件
 */
watch(
  () => props.editInformation,
  (newVal) => {
    // 监听编辑信息列表 如果有数据 进行弹窗数据赋值
    if (newVal) {
      libraryInformation.value = newVal;
      newVal?.videoName && videoEcho(newVal); // 如果有视频名称进行回显展示
    }
  },
);
/**
 * 视频回显
 * @param newVal 编辑信息
 */
const videoEcho = (newVal) => {
  // 获取到视频名称和视频id 进行展示和下载
  videoAttachmentList.value.push({
    fileName: newVal.videoName,
    id: newVal.videoId,
  });
};
/**
 * 案例库预览
 */
const casePreview = () => {
  // 获取到案例库详细内容 打开预览弹窗展示
  descriptionList.value = libraryInformation.value;
  proxy.$refs?.contentDialogRef.show(true);
};
/**
 * 弹窗保存/提交
 */
const informationSubmission = (action) => {
  // 如果没有内容(默认没有内容会返回"<p><br></p>") 则设置为空字符串 否则返回案例内容
  libraryInformation.value.caseContent = contentInitialization(libraryInformation.value.caseContent);
  // 弹窗数据效验
  proxy.$refs.libraryFormRef.validate((valid) => valid && emit(action, libraryInformation.value));
};
/**
 * 内容初始化
 * @param content 需要转换的当前字段
 */
const contentInitialization = (content) => {
  return content === "<p><br></p>" ? "" : content;
};
/**
 * 弹窗信息校验成功后提交
 */
const submit = () => {
  emit("informationSubmit", libraryInformation.value);
};
/**
 * 提交审核
 */
const reviewAndSubmit = (value, type) => {
  proxy.$refs.libraryFormRef.validate((valid) => valid && submitForReview(value, type));
};
/**
 * 审核通过/不通过
 * @param value
 * @param type
 */
const submitForReview = (value, type) => {
  const { id, currentOpinion } = libraryInformation.value;
  const data = {
    id,
    value,
    type,
    currentOpinion, // 审核意见
  };
  emit("submitForReview", data);
};
/**
 * 打开弹窗
 */
const addShow = async () => {
  dialogVisible.value = true; // 打开弹窗
  proxy.resetForm("libraryFormRef"); // 清空表单信息
};
/**
 * 编辑打开弹窗
 */
const editShow = () => {
  proxy.$refs?.libraryFormRef?.clearValidate(); // 清除校验
};
/**
 * 附件上传请求
 * @param files 用户上传的附件文件
 * @param type 当前删除的附件类型
 */
const handleUploadRequest = async (files, type) => {
  try {
    proxy.$modal.loading("请稍后...");
    uploading.value = true; // 打开进度条
    percentage.value = 0; // 进度条百分比 默认从0开始
    const formData = new FormData();
    formData.append("file", files.file); // 文件列表
    const { data } = await talentPoolUpload(props.libraryTypeId, formData);
    percentage.value = 100; // 上传成功后 进度条展示100%
    ElMessage.success("上传成功");
    // 获取到文件id和附件名称 进行展示和下载
    const file = {
      id: data.id,
      fileName: files.file.name,
    };
    if (type !== "video") {
      // 如果不是视频上传 则添加在附件列表中
      libraryInformation.value.fileList.push(file);
      return;
    }
    // 如果是视频上传 获取到视频id和视频名称 进行提交传值
    videoAssignment(data.id, files.file.name);
    videoAttachmentList.value.push(file);
  } catch (error) {
    videoAttachmentList.value = []; // 上传失败后 清空视频列表
  } finally {
    proxy.$modal.closeLoading();
    // 延时1秒关闭进度条
    setTimeout(() => {
      uploading.value = false; // 关闭进度条
    }, 1000);
  }
};
/**
 * 附件上传
 * @param url 各类库id地址
 * @param data 上传的附件信息
 */
const talentPoolUpload = (url, data) => {
  return request({
    url: `manage/${url}/upload`,
    method: "post",
    data,
    headers: {
      "Content-Type": "multipart/form-data",
    },
    // onUploadProgress 配置该属性代表允许为上传处理进度事件
    onUploadProgress: (progressEvent) => {
      // 实时获取最新上传进度 计算百分比：将已加载的量乘以 100，然后除以总载入量，得到一个表示完成百分比的数值。并四舍五入
      const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
      // 文件上传后 后台数据库还要进行保存, 这段进度是检测不到的 所以用99%进度来代替 只有接口返回成功后 展示100%进度
      percentage.value = percentCompleted >= SHOW_PROGRESS_AFTER_UPLOAD ? SHOW_PROGRESS_AFTER_UPLOAD : percentCompleted;
    },
  });
};
/**
 * 附件删除
 * @param index 当前删除的附件索引
 * @param type 当前删除的附件类型
 */
const handleDelete = (index, type) => {
  ElMessage.success("删除成功");
  if (type !== "video") {
    libraryInformation.value.fileList.splice(index, 1);
    return;
  }
  // 清空视频id和视频名称
  videoAssignment();
  // 当为视频上传的时候，清空选项
  videoAttachmentList.value = [];
};
/**
 * 视频上传赋值
 * @param id 视频id
 * @param name 视频名称
 */
const videoAssignment = (id, name) => {
  // 如果有id和name 则赋值 没有则清空
  libraryInformation.value.videoId = id ?? "";
  libraryInformation.value.videoName = name ?? "";
};
/**
 * 关闭弹窗的回调
 */
const closeDialog = () => {
  // 关闭后清空视频和附件列表 否则下一次打开弹窗有缓存问题
  videoAttachmentList.value = [];
  libraryInformation.value.fileList = [];
};
/**
 * 选人框点击事件
 * @param type 选择类型 branch: 支部, personnel: 人员
 */
const userSelectClick = (type) => {
  // 人员选择类型 打开人员选择框
  personnelOrBranch.value = type;
  personnelSelectionDialog.value.showDialog(true);
  const { userName, partyOrgName, userId } = libraryInformation.value;
  if (!userName) {
    personnelEcho.value = [];
    return;
  }
  const userNameArray = userName.split("；");
  const userIdArray = userId.split("；");
  const combineArray = userNameArray.map((name, index) => {
    return {
      label :  name,
      ygId: userIdArray[index] || "",
      orgShortName: partyOrgName,
    }
  })
  // 如果有默认人员 则进行人员回显 当前是单选 所以只返回给一条数据
  personnelEcho.value = !userName ? [] : combineArray;
};
/**
 * 获取部门信息和公司信息
 * @param id 人员id/支部id
 * @param branchOrCompany true: 获取公司; false: 获取支部;
 */
const getBranchInformation = async (id, branchOrCompany) => {
  try {
    proxy.$modal.loading("请稍后...");
    // 通过id获取部门信息
    const { data } = branchOrCompany ? await queryCompany(id) : await queryUsers(id);
    // 如果没有数据 则提示并返回
    if (!data.data) {
      return;
    }
    // 获取到支部信息和公司信息
    const { orgName, orgShortName, orgUUID: partyOrgDn, companyName, companyDn } = data.data;
    const list = { partyOrgName: orgName || orgShortName, partyOrgDn, companyName, companyDn };
    // 添加到人员信息列表中
    Object.assign(libraryInformation.value, list);
  } catch (error) {
    ElMessage.error(error);
  } finally {
    proxy.$modal.closeLoading();
  }
};
/**
 * 人员选择框赋值封装
 * @param name 人员姓名/支部名称
 * @param id 人员id/支部id
 * @param userName 人员姓名
 * @param ygId 人员id
 */
const userSelectAssign = (name, id, userName, ygId) => {
  libraryInformation.value[name] = userName;
  libraryInformation.value[id] = ygId;
};

/**
 * 支部选择弹窗提交
 * @param value 数据
 */
const branchSubmit = async (value) => {
  // 单选 默认只有一个对象 从第一个里面获取orgUUID 调用接口获取到支部信息
  const userSelect = value[0];
  const userName = lodash.join(lodash.map(value, 'label'), '；')
  const ygId = lodash.join(lodash.map(value, 'ygId'), '；')
  const data = personnelOrBranch.value === "branch";
  // 如果是支部 不需要赋值人员信息; 如果是人员 则需要赋值人员信息
  !data && userSelectAssign("userName", "userId", userName, ygId);
  await getBranchInformation(userSelect.ygId, data);
};
/**
 * 人员删除
 */
const personnelDeletion = () => {
  // 清空人员信息
  userSelectAssign("userName", "userId");
};
defineExpose({
  addShow,
  editShow,
  dialogVisible,
});
</script>

<style scoped lang="less">
// 弹窗
:deep(.dialog-content) {
  padding: 10px 80px 30px;
  // 人员选择输入框
  .personnel-input {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    border: 1px solid #dddfe6;
    border-radius: 5px;
    padding: 0 10px;
    cursor: pointer;
    min-height: 35px;
    .input-personnelList {
      color: #a9abb2;
      font-size: 14px;
    }
  }
}
</style>
